#ifndef SGU_SGU_H
#define SGU_SGU_H

#ifndef __GNUC__
	#error "GNU C++ compiler version 3.2 or greater required"
#endif

#if(__GNUC__ < 3)
	#error "GNU C++ compiler version 3.2 or greater required"
#endif

#if((__GNUC__ == 3) && (__GNUC_MINOR__ < 2))
	#error "GNU C++ compiler version 3.2 or greater required"
#endif

#ifdef __linux__
	#define SGU_LINUX
	#if(SGU_PLATFORM!=LINUX)
		#error "Platform mismatch"
	#endif
#endif

#ifdef __FreeBSD__
	#define SGU_FREEBSD
	#if(SGU_PLATFORM!=FREEBSD)
		#error "Platform mismatch"
	#endif
#endif

#ifdef __CYGWIN__
	#define SGU_CYGWIN
	#if(SGU_PLATFORM!=CYGWIN)
		#error "Platform mismatch"
	#endif
	#define _GLIBCPP_USE_WSTRING
#endif


#if (!(defined(SGU_LINUX)||defined(SGU_CYGWIN)||defined(SGU_FREEBSD)))
	#error "Unsupported platform"
#endif


#if (defined(SGU_USEDYNAMIC) && defined(SGU_USESTATIC))
	#error "Static && dynamic error"
#endif

#if (defined(SGU_BUILD) == (defined(SGU_USEDYNAMIC) || defined(SGU_USESTATIC)))
	#error "Use && build error"
#endif


#define _REENTRANT

#ifndef NDEBUG
	#define SGU_DEBUG
#endif

#define SGU_NS_BEGIN namespace SGU {
#define SGU_NS_END }


#include <unistd.h>
#include <string.h>
#include <stdlib.h>
//#include <pthread.h>
#include <fcntl.h>
#include <assert.h>
#include <limits.h>
#include <float.h>
#include <math.h>
#include <stdint.h>
#include <syslog.h>

#include <sys/file.h>
#include <sys/types.h>
#include <sys/stat.h> 
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include <set>
#include <vector>
#include <map>
#include <complex>
#include <stack> 
#include <list>
#include <string>
#include <sstream>
#include <limits>
#include <memory>

SGU_NS_BEGIN

class Serializable;
class NoCopy;
class UsedObj;
class UserObj;
class DynObj;
class ConstSegment;
class Segment;
class DynamicSegment;
class Memory;
class Exception;

class BOStorage;
class BIStorage;
class TOStorage;
class TIStorage;

class TextOutput;
class TextInput;
class TextOutputFile;
class TextInputFile;

class Point2D;
class Vector2D;
class Versor2D;
class Segment2D;
class Line2D;
class SemiLine2D;
class Matrix22;
//class Box2D;
class Size2D;
class Transform2D;
class Arc2D;
class Circle2D;
class Ellipse2D;
class EllipticArc2D;
class Stat;
class Stat2D;
class stat3D;
class Point3D;
class Vector3D;
class Versor3D;
class Matrix33;
class Line3D;
class Plane3D;
class Transform3D;
class Segment3D;
class SemiLine3D;
class Triangle3D;
//class Box3D;
class Size3D;
class Polygon3D;

class Dxf;

SGU_NS_END

#include "defs.h"
#include "types.h"
#include "exception.h" 
#include "template.h"
#include "object.h"
#include "templcoll.h"
#include "memory.h"
#include "bstorage.h"
#include "tstorage.h"
#include "file.h"
#include "string.h"
#include "integer.h"
#include "real.h"
#include "linear2d.h"
#include "conic2d.h"
#include "linear3d.h"
#include "stats.h"
#include "text.h"
#include "dxf.h"

SGU_NS_BEGIN

bool SGU_isdynamic();


//! SGU library class
/*! Provide infos about library and platform */
class SGUlib
{
	public:
	SGUlib(const char * name)
	{
		#ifdef SGU_USESTATIC
		if(isDynamic())
		{
			fputs("SGU dynamic used as static.\n",stderr);
			abort();			
		}
		#endif

		#ifdef SGU_USEDYNAMIC
		if(!isDynamic())
		{
			fputs("SGU static used as dynamic.\n",stderr);
			abort();
		}
		#endif
		
		if(_s_single)
		{
			fputs("SGU double init.\n",stderr);
			abort();
		}
		
		#ifdef SGU_DEBUG
		if(!isDebug())
		#else
		if(isDebug())
		#endif
		{
			fputs("SGU Debug mismatch.\n",stderr);
			abort();
		}
		_name = strdup(name);
		init(_name);
		++_s_single;
	}

	virtual ~SGUlib()
	{
		term();
		free(_name);
		--_s_single;
	}

	static const char * queryPlatform();
	static bool isDebug();
	static bool isDynamic();
	static const char * queryTimeStamp();
	static int queryVersion();
	static const char * queryRelease();
	static const char * queryOwn();

	static std::string queryBanner();

	const char * queryName();


	private:
	static int _s_single;
	static const char * _s_timestamp;
	static const int _s_version;
	static const char * _s_release;
	static const char * _s_platform;

	static void check();
	static void init(const char *);
	static void term();

	char * _name;
};


//! Log error to standard error logging system
/*! Used to log untrapped exceptions in destructors */
void logerr(int err, int fd, const char * scope);

/*! \mainpage
 *  In all pages:
 *  - comments using <tt>codestyle</tt> are written using C++ syntax
 *  - comments using \f$formula style\f$ are written using mathematical conventions where:
 *   - symbol \f$=\f$ is used for equality
 *   - symbol \f$\models\f$ is used for assignment
 *	 .
 *  .
 */


SGU_NS_END

#endif
